package com.binance.gateway.filter.auth;

import com.binance.gateway.app.base.dto.SessionDto;
import com.binance.gateway.app.base.helper.BaseHelper;
import com.binance.gateway.app.base.helper.SessionHelper;
import com.binance.gateway.app.constant.Constant;
import com.binance.gateway.constant.GwFilterOrders;
import com.binance.gateway.util.URIUtil;
import com.ctrip.framework.apollo.ConfigService;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;
import org.springframework.web.util.WebUtils;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

@Component
@Slf4j
public class GetUserIdFilter extends ZuulFilter {
    @Resource
    private SessionHelper sessionHelper;
    @Resource
    private BaseHelper baseHelper;

    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return GwFilterOrders.AUTH;
    }

    @Override
    public boolean shouldFilter() {
        RequestContext ctx = RequestContext.getCurrentContext();
        String uri = URIUtil.normalize(ctx.getRequest());
        String[] publicAuthUrls = ConfigService.getAppConfig().getArrayProperty("public.auth.url", ",", null);
        if (publicAuthUrls != null && ArrayUtils.contains(publicAuthUrls, uri)) {
            return true;
        }
        return false;
    }

    @Override
    public Object run() throws ZuulException {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        String token = request.getHeader(Constant.HEADER_TOKEN);
        SessionDto sessionVo;
        if (baseHelper.isFromWeb()) {
            // Web端登录则去cookie获取
            if (StringUtils.isEmpty(token)) {
                Cookie tokenCookie = WebUtils.getCookie(request, Constant.COOKIE_TOKEN);
                if (tokenCookie != null) {
                    token = tokenCookie.getValue();
                }
            }
            sessionVo = sessionHelper.getSession(token);
            if (sessionVo == null || (!baseHelper.isValidCsrfToken(request, sessionVo, Constant.COOKIE_CSRFTOKEN)
                    && !baseHelper.isValidCsrfToken(request, sessionVo, Constant.COOKIE_NEW_CSRFTOKEN))) {
                log.info("isTokenExpire= {},token={}", sessionVo == null, StringUtils.left(token, Constant.TOKEN_SHOW_LEN));
                return null;
            }
        } else {
            // app验证token
            sessionVo = sessionHelper.getSession(token);
            if (sessionVo == null) {
                log.info("app token is expire,token={}", StringUtils.left(token, Constant.TOKEN_SHOW_LEN));
                return null;
            }
        }
        ctx.set(Constant.SESSION_INFO_KEY, sessionVo);
        ctx.addZuulRequestHeader(Constant.HEADER_USER_ID, sessionVo.getUserId());
        ctx.addZuulRequestHeader(Constant.HEADER_USER_EMAIL, sessionVo.getEmail());
        return null;
    }

}
